Балу, ленивый бурый медведь,
который обучает волчат Закону Джунглей. Он может бродить, где ему вздумается,
потому что ест одни только орехи, мед и коренья.
Это случилось в
то время, когда медведь Балу обучал Маугли Закону Джунглей. Большой и важный
бурый медведь радовался способностям ученика, потому что волчата обычно
выучивают из Закона Джунглей только то, что нужно их Стае и племени. Но Маугли,
как детенышу человека, нужно было знать гораздо больше.
На занятиях по
арифметике Балу придумал следующую игру. Надо было из числа 1 получить число n, при этом разрешалось текущее число
либо умножить на три, либо к текущему числу прибавить 4. За каждое умножение
Балу давал пять тумаков, а за каждое сложение 2 тумака. Например,
в первом случае
получишь десять тумаков, во втором – двенадцать.
Маугли
естественно лучше всех освоил арифметику и быстро придумал, как решить задачу,
получив наименьшее количество тумаков. Он также заметил, что не всегда можно
выполнить задание хитрого медведя…
Вход. Одно целое
число n (1 ≤ n ≤ 109).
Выход. Вывести
минимальное количество тумаков, которые можно получить за решение задачи. Если
решить задачу невозможно, то вывести число 0.
Пример входа |
Пример выхода |
21 |
10 |
РЕШЕНИЕ
структуры
данных – map, рекурсия
Обозначим через
f(n) минимальное количество тумаков,
которые можно получить за решение задачи.
Тогда:
·
f(n)
= min (f(n / 3) + 5, f(n – 4) + 2 ), если n делится на 3.
·
f(n)
= f(n – 4) + 2 , если n не делится на 3.
Например, для n ≤ 107 вычислим и
запомним значения функции f(n) в
линейном массиве m. Для больших
значений n запоминания проведем в
структуре map.
Объявим структуры для запоминания значений функции f(n).
#define MAX 10000000
int m[MAX];
map<int, int> mp;
Рекурсивное вычисление с
запоминанием функции f(n).
int f(int n)
{
if (n <
MAX) return m[n];
if (mp[n]
> 0) return mp[n];
if (n % 3 ==
0)
mp[n] = f(n/3) + 5;
else
mp[n] = f(n-4) + 2;
return mp[n];
}
Основная часть программы. Положим m[i] = - µ, если
значение i Маугли получить не сможет
никакими действиями. Вычислим f(i)
для i до 107 и запомним их
в m[i].
m[0] = -MAX; m[1] = 0;
m[2] = -MAX; m[3] = 5; m[4] = -MAX; m[5] = 2;
for(i = 6; i < MAX; i++)
if(i % 3 == 0)
m[i] = min(m[i / 3] + 5, m[i - 4] + 2);
else
m[i] = m[i - 4] + 2;
Читаем входное значение n. Вычисляем и выводим ответ.
scanf("%d",&n);
res = f(n);
Если res окажется меньше 0, то решить задачу
невозможно, выводим число 0.
if (res < 0) res = 0;
printf("%d\n",res);
import java.util.*;
public class Main
{
static Map<Integer, Integer> mp = new
HashMap<Integer, Integer>();
static int MAX = 10000000;
static int m[] = new int[MAX];
public static int f(int n)
{
if (n < MAX) return m[n];
if (mp.containsKey(n)) return mp.get(n);
if (n % 3 == 0)
mp.put(n,f(n/3) + 5);
else
mp.put(n,f(n-4) + 2);
return mp.get(n);
}
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
m[0] =
-MAX; m[1] = 0; m[2] = -MAX; m[3] = 5;
m[4] = -MAX; m[5] = 2;
for(int i = 6; i < MAX; i++)
if(i % 3 == 0)
m[i] = Math.min(m[i / 3] + 5, m[i - 4] + 2);
else
m[i] = m[i - 4] + 2;
int n = con.nextInt();
int res = f(n);
if (res < 0) res = 0;
System.out.println(res);
con.close();
}
}